package com.zyf.project.binaryproto.specification.impl;

import com.zyf.project.binaryproto.annotation.DataField;
import com.zyf.project.binaryproto.specification.BinarySliceSpecification;
import com.zyf.project.binaryproto.specification.DataSpecification;
import com.zyf.project.binaryproto.specification.FieldSpecification;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * <h1>{@link DataSpecification} 的实现</h1>
 *
 * @author Zhou Yifan
 */
public class DataSpecificationInfo implements DataSpecification {

    private final int code;
    private final long version;
    private final String name;
    private final String description;

    private final List<FieldSpecification> fieldList;
    private final List<BinarySliceSpecification> sliceList;

    public DataSpecificationInfo(int code, long version, String name, String description, BinarySliceSpecification[] slices,
                                 FieldSpecification[] fields) {
        this.code = code;
        this.version = version;
        this.name = name;
        this.description = description;
        this.fieldList = Collections.unmodifiableList(Arrays.asList(fields));
        this.sliceList = Collections.unmodifiableList(Arrays.asList(slices));
    }

    /**
     * 数据契约的类型编码
     *
     * @return int 值
     */
    @Override
    public int getCode() {
        return code;
    }

    /**
     * <p>数据契约的版本</p>
     * <p>由类型编码 {@link #getCode()} 和字段列表 {@link #getFields()} 进行哈希生成的 64 位整数</p>
     *
     * @return long 值
     */
    @Override
    public long getVersion() {
        return version;
    }

    /**
     * 名字
     *
     * @return 字符串
     */
    @Override
    public String getName() {
        return name;
    }

    /**
     * 描述
     *
     * @return 字符串
     */
    @Override
    public String getDescription() {
        return description;
    }

    /**
     * <p>按定义顺序排列的字段格式标准的列表</p>
     * <p>字段顺序由 {@link DataField#order()} 定义</p>
     *
     * @return {@link FieldSpecification} 的 {@link List}
     */
    @Override
    public List<FieldSpecification> getFields() {
        return fieldList;
    }

    /**
     * 按顺序定义的二进制数据片段的格式标准的列表
     *
     * @return {@link BinarySliceSpecification} 的 {@link List}
     */
    @Override
    public List<BinarySliceSpecification> getSlices() {
        return sliceList;
    }

    @Override
    public String toString() {
        StringBuilder info = new StringBuilder();
        info.append(String.format("---------- DataContract[%s-%s] ----------%n", code, version));
        info.append(String.format("   code:%s%n", code));
        info.append(String.format("version:%s%n", version));
        info.append(String.format("   name:%s%n", name));
        info.append(String.format("   desc:%s%n", description));
        info.append("----- head -----\r\n");
        BinarySliceSpecification headSliceSpec = sliceList.get(0);
        info.append(String.format(
                "slice--::[dynamic:%s; repeatable:%s; length:%s; name:%s; desc:%s]%n",
                headSliceSpec.isDynamic(),
                headSliceSpec.isRepeatable(),
                headSliceSpec.getLength(),
                headSliceSpec.getName(),
                headSliceSpec.getDescription()
        ));

        info.append(String.format("----- fields[%s] -----%n", fieldList.size()));
        for (int i = 1; i < sliceList.size(); i++) {
            headSliceSpec = sliceList.get(i);
            info.append(String.format(
                    "slice-%s::[dynamic:%s; repeatable:%s; length:%s; name:%s; desc:%s]%n",
                    i,
                    headSliceSpec.isDynamic(),
                    headSliceSpec.isRepeatable(),
                    headSliceSpec.getLength(),
                    headSliceSpec.getName(),
                    headSliceSpec.getDescription()
            ));
        }

        return info.toString();
    }
}
